The need to control access to a common resource has been important since the advent of multi-threaded processing. Simply stated, there are situations where multiple tasks may wish to access the same resource. If one of those tasks is changing the contents of that resource, while the second task is attempting to read (or write) the contents of that resource, a race condition may occur.
Assume that there is a doubly linked list. Also assume that a first task wishes to add a new element in the middle of that list, between element 2 and element 3. To do this, the first task needs to modify the next-node link of element 2 to point to the new element. The first task also needs to modify the previous-node link of element 3 to point to the new element. Finally, the next-node link and previous-node link of the new element have to be set appropriately. Also assume that at the same time, a second task wishes to delete element 2. To do so, the second task will modify the next-node link of element 1 to point to the element pointed to by the next-node link of element 2. Similarly, it will modify the previous-node link of element 3 to point to the element pointed to by the previous-node link of element 2. Depending on the order that these various operations are performed, it is possible that the next-node link of element 1 points to the new element, while the previous-node link of element 3 still points to element 2.
To eliminate this, data structures known as locks, semaphores or mutex (mutual exclusion) have been devised. These data structures operate by allowing only one application or task to access the common resource at a time. When that task has completed its access to the common resource, the operating system is free to grant another task access to the common resource.
However, there may be times when the rigor of single access is inconvenient. For example, there is no issue in allowing multiple tasks read access to a common resource, as long as none of these tasks modify the contents of that common resource.
Therefore, it would be beneficial if there were an efficient locking mechanism that controlled access to a common resource. Further, it would be advantageous if that mechanism also implemented policy rules to maximize access to the common resource without risk of data integrity issues.